package cn.lingyangwl.agile.misc.order.service;

import cn.lingyangwl.agile.misc.order.assembly.*;
import cn.lingyangwl.agile.misc.order.mapper.*;
import cn.lingyangwl.agile.misc.order.model.*;
import cn.lingyangwl.agile.misc.order.model.entity.*;
import cn.lingyangwl.framework.mybatis.plus.utils.*;
import cn.lingyangwl.framework.tool.core.*;
import cn.lingyangwl.framework.tool.core.exception.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 订单
 *
 * @author shenguangyang
 */
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>
    implements IService<Order>, OrderService {
    @Resource
    private OrderAssembly orderAssembly;
    @Resource
    private OrderDetailAssembly orderDetailAssembly;
    @Resource
    private OrderDetailService orderDetailService;
    
    @Override
    public IPage<OrderResp> pageOrder(OrderQueryReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<Order> lqw = Order.lqw()
            .eq(StringUtils.isNotEmpty(req.getOrderNo()), Order::getOrderNo, req.getOrderNo())
            .eq(StringUtils.isNotEmpty(req.getMchTradeNo()), Order::getMchTradeNo, req.getMchTradeNo())
            .eq(StringUtils.isNotEmpty(req.getOrderStatus()), Order::getOrderStatus, req.getOrderStatus())
            .ge(Objects.nonNull(beginTime), Order::getCreatedAt, beginTime)
            .le(Objects.nonNull(endTime), Order::getCreatedAt, endTime)
            .orderByDesc(Order::getCreatedAt);
        IPage<Order> pageData = this.page(PageUtil.to(req), lqw);
        return PageUtil.to(pageData, orderAssembly::toOrderResp);
    }
    
    @Override
    public List<OrderResp> listOrder(OrderQueryReq req) {
        LambdaQueryWrapper<Order> lqw = Order.lqw()
            .eq(StringUtils.isNotEmpty(req.getOrderNo()), Order::getOrderNo, req.getOrderNo())
            .eq(StringUtils.isNotEmpty(req.getMchTradeNo()), Order::getMchTradeNo, req.getMchTradeNo())
            .eq(StringUtils.isNotEmpty(req.getOrderStatus()), Order::getOrderStatus, req.getOrderStatus())
            .eq(Objects.nonNull(req.getGoodsId()), Order::getGoodsId, req.getGoodsId())
            .orderByDesc(Order::getCreatedAt);
    	return this.list(lqw).stream().map(orderAssembly::toOrderResp).collect(Collectors.toList());
    }

    @Override
    public OrderResp getOrder(Long id) {
        Order entity = this.getById(id);
    	return orderAssembly.toOrderResp(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrder(OrderSaveReq req) {
        Order entity = orderAssembly.toOrder(req);
        boolean ret = this.save(entity);
        if (!ret) {
            throw new BizException("订单保存失败");
        }
        List<OrderDetail> detailList = req.getDetailList().stream().map(orderDetailAssembly::toOrderDetail)
            .peek(e -> {
                e.setOrderId(entity.getId());
                e.setOrderNo(entity.getOrderNo());
            }).collect(Collectors.toList());
        orderDetailService.saveBatch(detailList);
        return true;
    }

    @Override
    public boolean updateOrder(OrderSaveReq req) {
        Order entity = orderAssembly.toOrder(req);
    	return this.updateById(entity);
    }

    @Override
    public boolean deleteOrder(Long id) {
    	return this.removeById(id);
    }
    
    @Override
    public boolean batchDeleteOrder(List<Long> ids) {
    	return this.removeByIds(ids);
    }
}
